package com.yht.weblog.jwt.filter;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yht.weblog.jwt.exception.UsernameOrPasswordNullException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;

/**
 * @author: yht
 * @date: 2023/12/7 16:58
 * @description: 用户认证过滤器
 **/
public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    /**
     * JwtAuthenticationFilter类的构造函数
     */
    public JwtAuthenticationFilter() {
        super(new AntPathRequestMatcher("/login", "POST"));
    }

    /**
     * 尝试对请求进行身份验证
     *
     * @param request HTTP请求对象
     * @param response HTTP响应对象
     * @return 身份验证结果
     * @throws AuthenticationException 身份验证异常
     * @throws IOException 输入流异常
     * @throws ServletException 表单验证异常
     */
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
        // 创建ObjectMapper对象
        ObjectMapper mapper = new ObjectMapper();

        // 读取请求的输入流并将其转换为JsonNode对象
        JsonNode jsonNode = mapper.readTree(request.getInputStream());
        // 从JsonNode对象中获取username节点
        JsonNode usernameNode = jsonNode.get("username");
        // 从JsonNode对象中获取password节点
        JsonNode passwordNode = jsonNode.get("password");

        // 判断usernameNode和passwordNode是否为空，以及username和password是否为空字符串
        if (Objects.isNull(usernameNode) || Objects.isNull(passwordNode) || StringUtils.isBlank(usernameNode.textValue())
                || StringUtils.isBlank(passwordNode.textValue())) {
            // 抛出用户名或密码不能为空的异常
            throw new UsernameOrPasswordNullException("用户名或密码不能为空");

        }

        // 获取username和password的值
        String username = usernameNode.textValue();
        String password = passwordNode.textValue();

        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken
                = new UsernamePasswordAuthenticationToken(username, password);
        return getAuthenticationManager().authenticate(usernamePasswordAuthenticationToken);
    }

}
